#![allow(unused_imports)]
use crate::app::module::talker;
use crate::app::server::conn;
use crate::app::server::message;
use std::collections::HashMap;
use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex, RwLock};
use once_cell::sync::OnceCell;
use crate::app::module::talker::Talker;

pub static RM: OnceCell<Arc<RwLock<RoomsManage>>> = OnceCell::new();

pub fn init_room(room_count:u16,max_talk:u16){
    let rm = RoomsManage::new(room_count,max_talk);
    let res = RM.set(Arc::new(RwLock::new(rm)));
    log_panic_result!(res);
    log_info_ln!("房间初始化成功，有房间{}个，每个房间容纳{}位", room_count,max_talk);
}

#[derive(Debug,Clone,Deserialize,Serialize)]
pub struct RoomInfo {
    pub id: u16,
    pub name: String,
    pub max_count: u16,
    pub now_count: u16,
}
#[derive(Debug,Clone,Deserialize,Serialize)]
pub struct RoomInfoList {
    pub rooms:Vec<RoomInfo>,
}

impl RoomInfo{
    pub fn new()->Self{
        RoomInfo{
            id:0,
            name:String::new(),
            max_count:0,
            now_count:0,
        }
    }
}

pub fn get_room_info()->(RoomInfoList,bool){
    let mut ri = vec![];
    let rmanage = match RM.get() {
        Some(s)=>{ Arc::clone(s)}
        None=>{ return (RoomInfoList{rooms:ri},false); }
    };
    let rlock = rmanage.read();
    match rlock {
        Err(e)=>{log_error_ln!("房间信息拉取失败:{}",e.to_string());return (RoomInfoList{rooms:ri},false);}
        Ok(o)=>{
            for (i,x) in o.rooms.iter() {
                let mut room_info = RoomInfo::new();
                room_info.id = i.clone();
                match x.read(){
                    Err(e)=>{
                        log_error_ln!("get_room_info {}",e.to_string());
                        room_info.name = "-1".to_string();
                    }
                    Ok(o)=>{
                        room_info.name = o.name.clone();
                        room_info.max_count = o.max_count;
                        room_info.now_count = o.now_count;
                    }
                }
                ri.push(room_info);
            }
        }
    }
    return (RoomInfoList{rooms:ri},true);
}

#[derive(Debug,Clone,Deserialize,Serialize)]
pub struct RoomDetails{
    room_id:u16,
    talkers:Vec<Talker>
}

pub fn join_room(rid:u16,talk_info:Talker,sender:Sender<message::Message>)->Result<RoomDetails,String>{
    let rmanage = match RM.get() {
        Some(s)=>{ Arc::clone(s)}
        None=>{ return Err("roommanage为空".to_string()); }
    };
    let rooms = match rmanage.read() {
        Err(e)=>{return Err(e.to_string());}
        Ok(o)=>{o}
    };
    let room_lock = match rooms.rooms.get(&rid) {
        Some(o)=>{o}
        None=>{return Err(format!("不正确的房间号：{} 未找到对应房间",rid));}
    };
    let talk = TalkerClient{
         talker: talk_info,
         send: Arc::new(Mutex::new(sender)),
    };
    let mut wroom = match room_lock.write() {
        Err(e)=>{return Err(e.to_string());}
        Ok(o)=>{o}
    };
    wroom.talkers.insert(talk.talker.iden_id.clone(), talk);
    drop(wroom);
    let rroom = match room_lock.read() {
        Err(e)=>{return Err(e.to_string());}
        Ok(o)=>{o}
    };
    let mut ts = vec![];
    for (_,item) in rroom.talkers.iter() {
        let user = item.talker.clone();
        ts.push(user);
    }
    Ok(RoomDetails{
        room_id:rid,
        talkers:ts,
    })
}

pub fn send_room_msg(rid:u16,msg:message::Message)->Result<(),String>{
    let rmanage = match RM.get() {
        Some(s)=>{ Arc::clone(s)}
        None=>{ return Err("roommanage为空".to_string()); }
    };
    let rooms = match rmanage.read() {
        Err(e)=>{return Err(e.to_string());}
        Ok(o)=>{o}
    };
    let room_lock = match rooms.rooms.get(&rid) {
        Some(o)=>{o}
        None=>{return Err(format!("不正确的房间号：{} 未找到对应房间",rid));}
    };
    let wroom = match room_lock.read() {
        Err(e)=>{return Err(e.to_string());}
        Ok(o)=>{o}
    };
    for (_,talk) in wroom.talkers.iter() {
        let sender = match talk.send.lock(){
            Err(e)=>{return Err(e.to_string());}
            Ok(o)=>{o}
        };
        if let Err(e) =  sender.send(msg.clone()){
            return Err(e.to_string());
        }
    }
    return Ok(())
}

#[derive(Debug)]
pub struct RoomsManage {
    rooms: HashMap<u16, Arc<RwLock<Room>>>,
}

impl RoomsManage {
    pub fn new(count: u16, max: u16) -> Self {
        let mut rm = RoomsManage {
            rooms: HashMap::new(),
        };
        for i in 0..count {
            rm.rooms.insert(i, Arc::new(RwLock::new(Room::new(i, max))));
        }
        rm
    }

    pub fn get_room_by_id(&mut self, rid: u16) -> Option<Arc<RwLock<Room>>> {
        if let Some(s) = self.rooms.get(&rid) {
            return Some(Arc::clone(s));
        }
        return None;
    }
}

#[derive(Debug)]
pub struct Room {
    pub id: u16,
    pub name: String,
    pub max_count: u16,
    pub now_count: u16,
    pub talkers: HashMap<String, TalkerClient>, // pub talkers:HashMap<>
}

#[derive(Debug)]
pub struct TalkerClient {
    pub talker: talker::Talker,
    pub send: Arc<Mutex<Sender<message::Message>>>,
}
impl TalkerClient{
    fn get_send(&self)->Result<Sender<message::Message>,String> {
         match self.send.lock() {
            Err(e)=>{Err(e.to_string())}
            Ok(o)=>{Ok(o.clone())}
        }
    }
}


impl Room {
    pub fn new(name: u16, max: u16) -> Self {
        Room {
            id: name,
            name: name.to_string(),
            max_count: max,
            now_count:0,
            talkers: HashMap::new(),
        }
    }
    pub fn insert(&mut self, talk: TalkerClient) {
        self.talkers.insert(talk.talker.iden_id.clone(),talk);
    }
    pub fn join_room(&mut self,tr:&talker::Talker,send:&Sender<message::Message>){
        let tc = TalkerClient{
            talker:tr.clone(),
            send:Arc::new(Mutex::new(send.clone())),
        };
        self.insert(tc);
    }
    pub fn delete(&mut self, ideen_id: &str) {
        self.talkers.remove(ideen_id);
    }
    pub fn send_msg(&mut self, msg: message::Message) {
        for (_, talker) in self.talkers.iter() {
            let tarc = match talker.get_send(){
                Err(e)=>{log_error_ln!("send_msg {}",e);continue;}
                Ok(o)=>{o}
            };
            if let Err(e) = tarc.send(msg.clone()) {
                log_error_ln!("群消息发送失败 {}", e.to_string());
            }
        }
    }
}
